﻿using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using HandyControl.Controls;
using HandyControl.Data;
using HardToolApp.Model;
using HardToolApp.Tool;
using HardToolApp.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HardToolApp.ViewModel
{
    [ViewModelHelper("PWM", typeof(PwmPage), typeof(PwmModel),typeof(PwmModel.PWM), Sort = 5)]
    internal class PwmVM:PeripheralVM
    {
        public RelayCommand<PwmModel.PWM> SetCmd { get; set; }
        public RelayCommand<PwmModel.PWM> OpenCmd {  get; set; }
        public RelayCommand<PwmModel.PWM> CloseCmd {  get; set; }


        public PwmVM() 
        {
            SetCmd = new RelayCommand<PwmModel.PWM>(SetCommand);
            OpenCmd = new RelayCommand<PwmModel.PWM>(OpenCommand);
            CloseCmd = new RelayCommand<PwmModel.PWM> (CloseCommand);
            ScriptVM.register("pwm_set", "(id,周期,占空比1~100)", "PWM", this.GetType(), "PWM设置", "0:操作成功,1:操作失败");
            ScriptVM.register("pwm_open", "(id,1：打开 0：关闭)", "PWM", this.GetType(), "IIC从机数据发送", "0:操作成功,1:操作失败");
        }
        public override void Rec(object t, byte[] b)
        {
            if (b[3] != (byte)CommCmd.COMM_PWM)
            {
                return;
            }
            if (b[5] != 0)
            {
                switch(b[4])
                {
                    case (byte)CommSubPWM.COMM_SUB_PWM_SET_PARAM:
                        Growl.Warning("参数设置失败");
                        break;
                    case (byte)CommSubPWM.COMM_SUB_PWM_OPEN_CLOSE:
                        Growl.Warning("开关PWM失败");
                        break;
                }
            }
            USBInfoVM.USBVm.AddMap((b[3] << 8) + b[4], b[5]);

        }

        void SetCommand(PwmModel.PWM t)
        {
            t.subCmd = (byte)CommSubPWM.COMM_SUB_PWM_SET_PARAM;
            Send(t);
        }
        void OpenCommand(PwmModel.PWM t)
        {
            t.subCmd = (byte)CommSubPWM.COMM_SUB_PWM_OPEN_CLOSE;
            t.NeedOpen = true;
            Send(t);
        }
        void CloseCommand(PwmModel.PWM t)
        {
            t.subCmd = (byte)CommSubPWM.COMM_SUB_PWM_OPEN_CLOSE;
            t.NeedOpen = false;
            Send(t);
        }

        public static object pwm_set(byte ID,UInt32 Freq,Double Duty)
        {
            int div = 1;
            for (; div < 65536; div++)
            {
                int temp = (int)(72000000 / Freq / div);
                if (temp <= 65536 && temp >= 100)
                {
                    int tick = (int)(72000000 / Freq / div);
                    int duty = (int)(tick * Duty / 100);
                    tick--;
                    duty--;
                    div--;
                    byte[] bytes = new byte[13];
                    bytes[0] = 0x55;
                    bytes[1] = 0xaa;
                    bytes[2] = (byte)bytes.Length;
                    bytes[3] = (byte)CommCmd.COMM_PWM;
                    bytes[4] = (byte)CommSubPWM.COMM_SUB_PWM_SET_PARAM;
                    bytes[5] = (byte)ID;
                    bytes[6] = (byte)(tick >> 8 & 0xff);
                    bytes[7] = (byte)(tick & 0xff);
                    bytes[8] = (byte)(div >> 8 & 0xff);
                    bytes[9] = (byte)(div & 0xff);
                    bytes[10] = (byte)(duty >> 8 & 0xff);
                    bytes[11] = (byte)(duty & 0xff);
                    bytes[12] = Common.chksum(bytes);
                    return USBInfoVM.USBVm.send(bytes);
                }
            }
            Growl.Warning("无法找到合适的分频系数");
            return 1;
        }
        public static object pwm_open(byte ID,byte op)
        {
            byte[] bytes = new byte[8];
            bytes[0] = 0x55;
            bytes[1] = 0xaa;
            bytes[2] = (byte)bytes.Length;
            bytes[3] = (byte)CommCmd.COMM_PWM;
            bytes[4] = (byte)CommSubPWM.COMM_SUB_PWM_OPEN_CLOSE;
            bytes[5] = ID;
            bytes[6] = op;
            bytes[7] = Common.chksum(bytes);
            return USBInfoVM.USBVm.send(bytes);
        }
        #region PWM
        public override void Send(Peripheral peripheral)
        {
            PwmModel.PWM m = peripheral as PwmModel.PWM;
            if (m.subCmd == (byte)CommSubPWM.COMM_SUB_PWM_SET_PARAM)
            {
                pwm_set(m.ID,m.Freq,m.Duty);
            }
            else if (m.subCmd == (byte)CommSubPWM.COMM_SUB_PWM_OPEN_CLOSE)
            {
                pwm_open(m.ID, (byte)(m.NeedOpen == true ? 1 : 0));
            }
        }
        #endregion
    }
}
